// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "content/shell/browser/layout_test/layout_test_content_browser_client.h"

#include "base/memory/ptr_util.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/resource_dispatcher_host.h"
#include "content/public/browser/storage_partition.h"
#include "content/shell/browser/layout_test/blink_test_controller.h"
#include "content/shell/browser/layout_test/layout_test_bluetooth_fake_adapter_setter_impl.h"
#include "content/shell/browser/layout_test/layout_test_browser_context.h"
#include "content/shell/browser/layout_test/layout_test_browser_main_parts.h"
#include "content/shell/browser/layout_test/layout_test_message_filter.h"
#include "content/shell/browser/layout_test/layout_test_notification_manager.h"
#include "content/shell/browser/layout_test/layout_test_resource_dispatcher_host_delegate.h"
#include "content/shell/browser/shell_browser_context.h"
#include "content/shell/common/layout_test/layout_test_switches.h"
#include "content/shell/common/shell_messages.h"
#include "content/shell/renderer/layout_test/blink_test_helpers.h"
#include "services/service_manager/public/cpp/interface_registry.h"

namespace content {
namespace {

    LayoutTestContentBrowserClient* g_layout_test_browser_client;

} // namespace

LayoutTestContentBrowserClient::LayoutTestContentBrowserClient()
{
    DCHECK(!g_layout_test_browser_client);

    layout_test_notification_manager_.reset(new LayoutTestNotificationManager());

    g_layout_test_browser_client = this;
}

LayoutTestContentBrowserClient::~LayoutTestContentBrowserClient()
{
    g_layout_test_browser_client = nullptr;
}

LayoutTestContentBrowserClient* LayoutTestContentBrowserClient::Get()
{
    return g_layout_test_browser_client;
}

LayoutTestBrowserContext*
LayoutTestContentBrowserClient::GetLayoutTestBrowserContext()
{
    return static_cast<LayoutTestBrowserContext*>(browser_context());
}

LayoutTestNotificationManager*
LayoutTestContentBrowserClient::GetLayoutTestNotificationManager()
{
    return layout_test_notification_manager_.get();
}

void LayoutTestContentBrowserClient::RenderProcessWillLaunch(
    RenderProcessHost* host)
{
    ShellContentBrowserClient::RenderProcessWillLaunch(host);

    StoragePartition* partition = BrowserContext::GetDefaultStoragePartition(browser_context());
    host->AddFilter(new LayoutTestMessageFilter(
        host->GetID(),
        partition->GetDatabaseTracker(),
        partition->GetQuotaManager(),
        partition->GetURLRequestContext()));

    host->Send(new ShellViewMsg_SetWebKitSourceDir(GetWebKitRootDirFilePath()));
}

void LayoutTestContentBrowserClient::ExposeInterfacesToRenderer(
    service_manager::InterfaceRegistry* registry,
    RenderProcessHost* render_process_host)
{
    scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner = content::BrowserThread::GetTaskRunnerForThread(
        content::BrowserThread::UI);
    registry->AddInterface(
        base::Bind(&LayoutTestBluetoothFakeAdapterSetterImpl::Create),
        ui_task_runner);
}

void LayoutTestContentBrowserClient::OverrideWebkitPrefs(
    RenderViewHost* render_view_host,
    WebPreferences* prefs)
{
    BlinkTestController::Get()->OverrideWebkitPrefs(prefs);
}

void LayoutTestContentBrowserClient::ResourceDispatcherHostCreated()
{
    set_resource_dispatcher_host_delegate(
        base::WrapUnique(new LayoutTestResourceDispatcherHostDelegate));
    ResourceDispatcherHost::Get()->SetDelegate(
        resource_dispatcher_host_delegate());
}

void LayoutTestContentBrowserClient::AppendExtraCommandLineSwitches(
    base::CommandLine* command_line,
    int child_process_id)
{
    command_line->AppendSwitch(switches::kRunLayoutTest);
    ShellContentBrowserClient::AppendExtraCommandLineSwitches(command_line,
        child_process_id);
    if (base::CommandLine::ForCurrentProcess()->HasSwitch(
            switches::kAlwaysUseComplexText)) {
        command_line->AppendSwitch(switches::kAlwaysUseComplexText);
    }
    if (base::CommandLine::ForCurrentProcess()->HasSwitch(
            switches::kEnableFontAntialiasing)) {
        command_line->AppendSwitch(switches::kEnableFontAntialiasing);
    }
    if (base::CommandLine::ForCurrentProcess()->HasSwitch(
            switches::kStableReleaseMode)) {
        command_line->AppendSwitch(switches::kStableReleaseMode);
    }
    if (base::CommandLine::ForCurrentProcess()->HasSwitch(
            switches::kEnableLeakDetection)) {
        command_line->AppendSwitchASCII(
            switches::kEnableLeakDetection,
            base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
                switches::kEnableLeakDetection));
    }
}

BrowserMainParts* LayoutTestContentBrowserClient::CreateBrowserMainParts(
    const MainFunctionParams& parameters)
{
    set_browser_main_parts(new LayoutTestBrowserMainParts(parameters));
    return shell_browser_main_parts();
}

PlatformNotificationService*
LayoutTestContentBrowserClient::GetPlatformNotificationService()
{
    return layout_test_notification_manager_.get();
}

} // namespace content
